
#include "xlx_platform.h"
#include "xlx_core.h"
#include "xlx_tmsapi.h"
#include "xlx_config.h"
#include "xlx_configfile.h"
#include "xlx_action.h"
#include "xlx_version.h"
#include "xlx_tms_service.h"

//#include "tutu_fota.h"

#define OTA_VER_FILE "tmsota.dat"

static const char* TAG = "TmsSrv";

static TMSContext _pri_tms_ctx1 = {0};
static char _pri_tms_cmdbuf[1024] = {0};
static int _pri_tms_delay_ota_time = -1;
static char _pri_tms_enable_ota = 0;

//有升级任务前，通知具体任务信息
static void tututms_on_ota_start(int t,TMSOtaInfo *info){
    _pri_tms_delay_ota_time = info->delay;
    _pri_tms_enable_ota = 0;

    TUTULOG("<%s> tid=%ld delay=%d",info->version,info->tid,info->delay);

    if(strcmp(get_current_outside_sw_version(),info->version) == 0){
        //如果下发的软件版本号和设备当前一致，则直接上报升级成功
        tmsapi_req_upload_ota_status(&_pri_tms_ctx1,info->tid,0x03,get_current_outside_sw_version());
        return;
    }

    tmsapi_req_ota_file(&_pri_tms_ctx1,info->tid,1,4);

    //还需要保存版本号和tid，升级成功后需要使用这2个参数上报升级成功
    g_tutufile.write_file(OTA_VER_FILE,(char*)info,sizeof(TMSOtaInfo));
}


static char tututms_agps_file_recv(u16 agps_file_size,char *data,int len){
    return 0;
}

//接收到服务器下发的ota文件片段
//这里的文件，服务器只下发一个文本文件，用来跳转到对应的http服务器去下载真正的ota文件
static char tututms_ota_file_recv(u32 ota_file_size,char *data,int len){
    char *argv[3]={0};
    char *token = NULL;
    char line[32] = {0};
    char *p = line;
    int i = 0;

    if(len > 0){
        memcpy(line,data,len > 32 ? 31 : len);

        //根据逗号分割提取参数
        for (i = 0; i < 3; i++)
        {
            argv[i] = p;
            token = strstr(p,",");
            if(token){
                *token = '\0';
                p = token + 1;
            }else{
                break;
            }
        }

        TUTULOG("recv ota file size=%d  [%s]",len,line);
        
        //必须要有2个参数,ip和端口号
        if(i >= 1){
            g_tutuparam.fota_ipaddr[0] = 0;
            g_tutuparam.fota_port = 0;
            

            //fota服务器ip
            if(1 == xlx_str_is_ip(argv[0])){//如果是ip
                memset(g_tutuparam.fota_ipaddr,0,15);
                xlx_strcopy(g_tutuparam.fota_ipaddr,15,argv[0]);
            }else{
                g_tutuos.getaddress(argv[0],g_tutuparam.fota_ipaddr,16);
            }

            //fota服务器端口号
            g_tutuparam.fota_port = atoi(argv[1]);


            if(g_tutuparam.fota_ipaddr[0] != 0 && g_tutuparam.fota_port != 0){
                TUTULOG("recv ota file done!");
                _pri_tms_enable_ota = 1;
            }
        }
    }
    

    return 0;
}

//处理tms发过来的指令，全部采用at权限执行
static void tututms_on_cmd(int t,int seq,char *str){
    char *argv[6]={0};
    char *p = str;
    char *token = NULL;
    int i = 0;

    //解析字符串
    for ( i = 0; i < 6; i++)
    {
        argv[i] = p;
        token = strstr(p,",");
        if(token){
            *token = '\0';
            p = token + 1;
        }else{
            break;
        }
    }

    //处理指令
    xlx_action_process_at_data(_pri_tms_cmdbuf,i + 1,argv);

    //回复服务器结果
    tmsapi_rsp_command(&_pri_tms_ctx1,seq,t,_pri_tms_cmdbuf);
}


//读取云端参数的结果
static void tututms_cloud_read_value(int group_id,char *data,int len){

}


//初始化tms接口的回调参数
static void tututms_init_delegate(TMSContext *m){
    TMSDelegate d = {0};
    d.on_ota_start = tututms_on_ota_start;
    d.on_agps_file_recv = tututms_agps_file_recv;
    d.on_cloud_read_value = tututms_cloud_read_value;
    d.on_cmd = tututms_on_cmd;
    d.on_ota_file_recv = tututms_ota_file_recv;
    tmsapi_set_delegate(m,&d);
}

//上报固定信息
static void tututms_req_deviceinfo1(TMSContext *m){
    // char buf[32] = {0};
    TMSDeviceUpBody1 body1 = {0};

    //芯片id
    memcpy(body1.chip_id,(char*)(m->chip_id),16);

#if 1
    xlx_char2bcd(TEST_ICCID,20,(BCD_t*)body1.iccid);
    xlx_char2bcd(TEST_IMSI,16,(BCD_t*)body1.imsi);
#else
    //iccid
    if(1 == g_tuturil.get_iccid(buf,32)){
        //char转bcd编码
        xlx_char2bcd(buf,20,(BCD_t*)body1.iccid);
    }

    //imsi
    if(1 == g_tuturil.get_imsi(buf,32)){
        xlx_char2bcd(buf,16,(BCD_t*)body1.imsi);
    }
#endif
 
    //发送请求
    tmsapi_req_deviceinfo1(m,&body1,get_current_outside_sw_version());
}

//把升级结果上报给服务器
static void tututms_req_ota_status(TMSContext *m){
    TMSOtaInfo info = {0};
    unsigned long int size = 0;

    if(1 == g_tutufile.read_file(OTA_VER_FILE,(char*)(&info),&size) && size > 0){
        g_tutufile.my_delfile(OTA_VER_FILE);
        //相同，则说明版本已经更新成功
        if(strcmp(get_current_outside_sw_version(),info.version) == 0){
            tmsapi_req_upload_ota_status(m,info.tid,0x03,get_current_outside_sw_version());
        }
    }
}

typedef void (*TUTUTMS_SERVICE_CB)(TMSContext *m);

//简易请求tms服务器api
static void tututms_service_easy_request(TMSContext *m,TUTUTMS_SERVICE_CB cb){
    char buf[32] = {0};

    TUTULOG("Try to connect to TMS(%s:%d)...(%d:%s)",g_tutuservercfg.tms_srv_host,g_tutuservercfg.tms_srv_port,__LINE__,__FUNCTION__);
    // TUTULOG("Try to connect to TMS(%s:%d)...(%d:%s)",default_tms_host,default_tms_port,__LINE__,__FUNCTION__);
    if(
        g_tutuos.getaddress && 
        g_tutuos.getaddress(g_tutuservercfg.tms_srv_host,buf,32) == 1 && 
        -1 != tmsapi_connect_server(m,buf,g_tutuservercfg.tms_srv_port)
        ){

            //拷贝imei，如果imei没加载成功，则第一次请求的imei为空的
            memcpy(m->imei,g_tutuconfig.imei,8);

            TUTULOG("tmsdev.sockfd = %d",m->sockfd);

            //chip_id
            if(g_tutuos.get_cpuid16){
                g_tutuos.get_cpuid16((char*)m->chip_id);
            }

            if(cb){
                cb(m);
            }
            
            //网络交互
            tmsapi_run_data(m);
            tmsapi_close_socket(m);
        }
}

static void tututms_service_req1(TMSContext *m){
    tututms_req_ota_status(m);

    tututms_req_deviceinfo1(m);
}

typedef struct _TAG_LogBuffer {
    char send;//1：已经发送
    char write;//1：已经写入
    char strbuf[250];//日志内容，不超过250个字节
    struct _TAG_LogBuffer *next;
}LogBuffer_t;

#define LOGBUFFER_SIZE 5
static LogBuffer_t *_var_tututms_log_buffer_w = NULL;
static LogBuffer_t *_var_tututms_log_buffer_s = NULL;

//初始化日志buffer
static void tututms_service_logbuffer_init(){
    LogBuffer_t *pring = TUTUAlloc(sizeof(LogBuffer_t) * LOGBUFFER_SIZE);
    LogBuffer_t *p = NULL;
    int i = 0;

    _var_tututms_log_buffer_w = _var_tututms_log_buffer_s = p = pring;
    for(i = 1;i < LOGBUFFER_SIZE;i++){
        p->send = 0;
        p->write = 0;
        p->next = ++pring;
        p = p->next;
    }
    p->next = _var_tututms_log_buffer_w;
    p->send = 0;
    p->write = 0;

    
}

//是否有需要提交到服务器的log
static char tututms_service_has_commit_log(){
    LogBuffer_t *p = _var_tututms_log_buffer_s;
    if(p){
        if(p->write == 1 && p->send == 0){
            return 1;
        }
    }
    return 0;
}

//上传日志到服务器
static void tututms_service_commit_log(TMSContext *m){
    LogBuffer_t *p = NULL;
_p_agin:
    p = _var_tututms_log_buffer_s;
    if(p){
        if(p->write == 1 && p->send == 0){
            tmsapi_req_uploadlog(m,p->strbuf,strlen(p->strbuf));
            p->send = 1;
            _var_tututms_log_buffer_s = p->next;
            goto _p_agin;
        }
    }
}

//写日志到缓存区，待发送到服务器
void tututms_service_write_log(char *strlog){
    LogBuffer_t *p = _var_tututms_log_buffer_w;
    int n = strlen(strlog);

    if(n > 250){
        return;
    }

    if(p){
        if(p->send == 1 || (p->send == 0 && p->write == 0)){
            p->write = 0;
            p->send = 0;
            strcpy(p->strbuf,strlog);
            p->write = 1;
            _var_tututms_log_buffer_w = p->next;
        }
    }
}

static void tututms_service_task(void *params){
    char yes = 1;
    uint32_t t = 0;
    TMSContext *m = &_pri_tms_ctx1;
    
    tututms_init_delegate(m);
    tmsapi_set_timeout(m,30);       // kenglee
    
    tututms_service_logbuffer_init();
    TUTU_LOGI(TAG, "%s(%d)", __FUNCTION__, __LINE__); 
     
    xlx_char2bcd(TEST_ICCID, 20,(BCD_t*)g_tutuconfig.iccid);
    xlx_char2bcd(TEST_IMEI, 16,(BCD_t*)g_tutuconfig.imei);

    while (1)
    {
        if(yes == 1){
            // if(g_tuturil.get_sim_status && 5 == g_tuturil.get_sim_status()){//说明设备有插卡，并且流量是打开的
            if (1) {
                if(g_tutuconfig.imei[0] == 0 && 
                    g_tutuconfig.imei[1] == 0 &&
                    g_tutuconfig.imei[2] == 0 &&
                    g_tutuconfig.imei[3] == 0 &&
                    g_tutuconfig.imei[4] == 0 &&
                    g_tutuconfig.imei[5] == 0 &&
                    g_tutuconfig.imei[6] == 0 &&
                    g_tutuconfig.imei[7] == 0)
                {
                        //如果imei还没有获取到，则等待获取到imei才请求tms服务器
                }else{
                    TUTU_LOGI(TAG, "%s(%d)", __FUNCTION__, __LINE__); 
                    tututms_service_easy_request(m,tututms_service_req1);
                    yes = 0;
                }
            }
        }

        t += 10;
        if(t > 86400){//每24小时，请求一次tms服务器
            t = 0;
            yes = 1;
        }


        //按照服务器分配的时间，开始升级
        if(_pri_tms_enable_ota == 1){
            _pri_tms_delay_ota_time -= 2;
            TUTULOG("ota time %d",_pri_tms_delay_ota_time);
            if(_pri_tms_delay_ota_time < 0){
                _pri_tms_enable_ota = 0;
                //执行ota
                // !!!!!!!! 先屏蔽
                 TUTULOG("ota is running...");
                //tutu_fota_enter();
            }
        }

        if(1 == tututms_service_has_commit_log()){
            tututms_service_easy_request(m,tututms_service_commit_log);
        }

        g_tutuos.sleep(10);
        TUTULOG("Tms is running...");
    }

    vTaskDelete(NULL);
}


void xlx_tms_service_init(void){
    //tms服务交互
    g_tututhread.new_thread(1024*4, "TmsSrv", 6, tututms_service_task);
}